import { isEqual } from '@baize/wdk';
import { expect } from '@jest/globals';
import fse from 'fs-extra';
import path from 'path';

import { getJson5Obj } from '../../../../../../src/utils/json-util.js';
import { initExecuteCommand, runHvigorAsync } from '../../../../common/common';
import { commonJson5Operation } from '../../../../plugins/common-fun';
import {
  AbilityType,
  APIType,
  APIVersion,
  CaseLevel, CURRENT_HMOS_API,
  IsEnable,
  LanguageType,
  ModuleTemplateType,
  RuntimeOSType,
  SDKType
} from '../../../../plugins/project-builder/models/constants';
import { TestCaseBuilder } from '../../../../plugins/task-builder/task-case-builder';
import { ProjectBuildOption, TestCaseFun } from '../../../../plugins/task-builder/test-case';
import { TestTaskOptionBuilder } from '../../../../plugins/task-builder/test-task-option';

const projectBuilderOption: ProjectBuildOption = {
  template: {
    sdk: SDKType.Single,
    runtimeOS: RuntimeOSType.OpenHarmony,
    apiVersion: CURRENT_HMOS_API,
    language: LanguageType.ArkTs,
    abilityType: AbilityType.Application,
    entryTemplateType: ModuleTemplateType.EmptyAbility,
    apiType: APIType.STAGE
  },
  modulesOption: {}
};

const testFun: TestCaseFun = async (project, taskConfig, record) => {
  const moduleModel = project.getModule('entry');
  const moduleJson5Path = moduleModel.moduleModuleJsonPath();
  await commonJson5Operation(moduleJson5Path, async (json5) => {
    json5['module']['deviceTypes'] = ['default'];
  });

  const sysCapJsonPath = moduleModel.moduleSysCapJsonPath();
  fse.ensureFileSync(sysCapJsonPath);
  const sysCapJson = JSON.stringify({
    'devices': {
      'general': [
        'default'
      ],
      'custom': [
        {
          'm40': [
            'SystemCapability.ArkUI.ArkUI.Full',
            'SystemCapability.ArkUI.ArkUI.Lite',
            'SystemCapability.ArkUI.ArkUI.Napi',
            'SystemCapability.ArkUI.ArkUI.Libuv',
            'SystemCapability.ArkUI.UiAppearance'
          ]
        }
      ]
    },
    'production': {
      'addedSysCaps': [
        'SystemCapability.test.add',
        'SystemCapability.test.add1'
      ],
      'removedSysCaps': [
        'SystemCapability.test.add1'
      ]
    }
  }, null, 2);
  fse.writeFileSync(sysCapJsonPath, sysCapJson);

  const module = 'entry';
  const commandsHap = initExecuteCommand({
    mode: 'module',
    product: 'default',
    tasks: 'assembleHap',
    ...(module ? { module: `${module}@default` } : {})
  });

  const sysCapJsonObj = getJson5Obj(sysCapJsonPath);
  const customSysCapList = sysCapJsonObj['devices']['custom'][0]['m40'];
  const intersectedSysCap = customSysCapList;
  const result = await runHvigorAsync(project.projectRootPath(), commandsHap);
  intersectedSysCap.push('SystemCapability.test.add');
  const intermediateRpcidJsonPath =
    path.resolve(moduleModel.moduleRootPath(), 'build', 'default', 'intermediates', 'syscap', 'default', 'rpcid.json');
  const rpcidJsonObj = getJson5Obj(intermediateRpcidJsonPath);
  expect(isEqual(rpcidJsonObj['syscap'], intersectedSysCap)).toBe(true);
  expect(result.stdout).toContain('BUILD SUCCESSFUL');
};

TestCaseBuilder.builder()
  .caseName('OPENLAB_AIDE_ZOS_Build_N_Syscap_Stage_Project_Entry_007')
  .description(
    '模块定义设备类型不为空,syscap.json中general定义设备类型不为空且custom中定义syscap不为空,' +
    '构建成功且中间产物syscap目录下rpcid.json中包含general设备类型的syscap的交集与custom定义的syscap的交集' +
    '之后加上addedSysCaps中定义的syscap及删除removedSysCaps中定义的syscap.')
  .projectBuilderOption(projectBuilderOption)
  .taskConfig(TestTaskOptionBuilder.builder().caseLevel(CaseLevel.L2).ohpmInstall(IsEnable.Enable).build())
  .testFun(testFun)
  .load();
